home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Prog / T / TIFF Code.cpt / td.c < prev    next >
C/C++ Source or Header  |  1987-12-16  |  10KB  |  495 lines

  1. #include <types.h>
  2. #include <stdio.h>
  3.  
  4. #include "::TiffLibrary:tifflib.h"
  5. #include "td.h"
  6.  
  7. char            *tagName();
  8. char            *typeName();
  9. unsigned short    SwapShortBytes();
  10. unsigned long    SwapLongBytes();
  11. char            *gethex();
  12. char            hex();
  13.  
  14. char            *pgrm;
  15. char            *filename;
  16.  
  17. TiffHeader        header;
  18. Boolean            swapBytes;
  19.  
  20. main(argc, argv)
  21. int argc;
  22. char *argv[];
  23. {
  24.     int        fd;
  25.     Int16    ifdCount;
  26.     int        ifdOffset;
  27.     int        ifdNum;
  28.     
  29.     pgrm = argv[0];
  30.     if (argc != 2) {
  31.         fprintf(stderr, "usage: %s file\n", argv[0]);
  32.         exit(1);
  33.     }
  34.     filename = argv[1];
  35.     
  36.     if ((fd = open(filename, 0)) < 0) {
  37.         fprintf(stderr, "%s: can't open %s\n", pgrm, filename);
  38.         exit(1);
  39.     }
  40.     if (read(fd, &header, sizeof(header)) != sizeof(header)) {
  41.         fprintf(stderr, "%s: can't read %s\n", pgrm, filename);
  42.         exit(1);
  43.     }
  44.     if (header.byteOrder == INTEL) {
  45.         swapBytes = true;
  46.         header.version = SwapShortBytes(header.version);
  47.         header.dirOffset = SwapLongBytes(header.dirOffset);
  48.     }
  49.     else
  50.         swapBytes = false;
  51.         
  52.     printf("\nTIFF FILE %s:\n\nHeader:\n\n", filename);
  53.     printf("\tbyteorder='%c%c'(0x%X)\n\tversion=%d(0x%X)\n\tdirOffset=0x%lX\n",
  54.             header.byteOrder,
  55.             header.byteOrder, header.byteOrder >> 8,
  56.             header.version,
  57.             header.version,
  58.             header.dirOffset);
  59.     
  60.     ifdOffset = header.dirOffset;
  61.     for (ifdNum = 0; ifdOffset != 0; ifdNum++)
  62.         ifdOffset = readIFD(fd, ifdOffset);
  63.     
  64.     close(fd);
  65. }
  66.  
  67. Int32 readIFD(fd, ifdOffset)
  68. Int32    ifdOffset;
  69. {
  70.     unsigned char    *pByte;
  71.     int                i;
  72.     UInt16            ifdCount,
  73.                     *pShort;
  74.     TiffDirEntry    ifdEntry;
  75.     UInt32            offset;
  76.  
  77.     if (lseek(fd, ifdOffset, 0) < 0) {
  78.         fprintf(stderr, "%s: seek error: %s\n", pgrm, filename);
  79.         exit(1);
  80.     }
  81.     readShort(fd, &ifdCount);
  82.     printf("\nIFD: 0x%X(%d.) entries @0x%lX:\n\n",
  83.         ifdCount,
  84.         ifdCount,
  85.         ifdOffset);
  86.     for (i = 0; i < ifdCount; i++) {
  87.         if (read(fd, &ifdEntry, sizeof(ifdEntry)) != sizeof(ifdEntry)) {
  88.             fprintf(stderr, "%s: read error: %s\n", pgrm, filename);
  89.             exit(1);
  90.         }
  91.         if (swapBytes) {
  92.             ifdEntry.tag = SwapShortBytes(ifdEntry.tag);
  93.             ifdEntry.type = SwapShortBytes(ifdEntry.type);
  94.             ifdEntry.length = SwapLongBytes(ifdEntry.length);
  95.             if ( ((ifdEntry.length * typeSize(ifdEntry.type)) > 4) ||
  96.                  (ifdEntry.type == LONG) ) {
  97.                 /* it's a long value or a long offset so swap it */
  98.                 ifdEntry.valueOffset = SwapLongBytes(ifdEntry.valueOffset);
  99.             }
  100.             else if (ifdEntry.type == SHORT) {
  101.                 /* it's either one or two shorts, swap both anyway */
  102.                 pShort = (Int16 *)&ifdEntry.valueOffset;
  103.                 *pShort++ = SwapShortBytes(*pShort);
  104.                 *pShort   = SwapShortBytes(*pShort);
  105.             }
  106.             /* else type must be BYTE or ASCII so now swap needed */
  107.         }
  108.         printf("%s %3ld %s:",
  109.             tagName(ifdEntry.tag), ifdEntry.length, typeName(ifdEntry.type));
  110.         printValue(fd, ifdEntry.type, ifdEntry.length, ifdEntry.valueOffset);
  111.     }
  112.     readLong(fd, &ifdOffset);
  113.     return(ifdOffset);
  114. }
  115.  
  116. printValue(fd, type, length, offset)
  117. int        fd;
  118. UInt16    type;
  119. UInt32    length, offset;
  120. {
  121.     static char        buf[80];
  122.     unsigned char     *p;
  123.     unsigned char    Byte;
  124.     unsigned short    Short;
  125.     unsigned long    Long;
  126.     Rational        Rat;
  127.     int                size;
  128.     UInt32            n, oldOffset;
  129.  
  130.     size = typeSize(type);
  131.     if ((size * length) <= 4) {        /* value(s) in directory entry */
  132.         if (type == ASCII)
  133.             putchar('"');
  134.         for (n = 0; n < length; n++) { 
  135.             switch (type) {
  136.             case BYTE:
  137.                 printf("0x%X ",    (int)( ((unsigned char  *)(&offset))[n]));
  138.                 break;
  139.             case ASCII:
  140.                 printf("%c",    (int)( ((unsigned char  *)(&offset))[n]));
  141.                 break;
  142.             case SHORT:
  143.                 printf("0x%X ",    (int)( ((unsigned short *)(&offset))[n]));
  144.                 break;
  145.             case LONG:
  146.                 printf("0x%lX ",    offset);
  147.                 break;
  148.             }
  149.         }
  150.         if (type == ASCII)
  151.             putchar('"');
  152.     }
  153.     else {                            /* value(s) at given offset */
  154.         printf("values @0x%lX:",offset);
  155.         if ((oldOffset = lseek(fd, 0L, 1)) < 0) {
  156.             fprintf(stderr, "%s: seek error: %s\n", pgrm, filename);
  157.             exit(1);
  158.         }
  159.         if (lseek(fd, offset, 0) < 0) {
  160.             fprintf(stderr, "%s: seek error: %s\n", pgrm, filename);
  161.             exit(1);
  162.         }
  163.         putchar('\n');
  164.         if (type == ASCII)
  165.             printf("\t\"");
  166.         for (n = 0; n < length; n++) {
  167.             if (type != ASCII)
  168.                 putchar('\t');
  169.             switch (type) {
  170.             case BYTE:
  171.                 readByte(fd, &Byte);
  172.                  sprintf(buf, "0x%lX", Byte);
  173.                 pad(buf, 2 + (2 * sizeof(Byte)));
  174.                 printf("%s", buf);
  175.                 break;
  176.             case ASCII:
  177.                 readByte(fd, &Byte);
  178.                 putchar(Byte);
  179.                 break;
  180.             case SHORT:
  181.                 readShort(fd, &Short);
  182.                  sprintf(buf, "0x%lX", Short);
  183.                 pad(buf, 2 + (2 * sizeof(Short)));
  184.                 printf("%s", buf);
  185.                 break;
  186.             case LONG:
  187.                 readLong(fd, &Long);
  188.                  sprintf(buf, "0x%lX", Long);
  189.                 pad(buf, 2 + (2 * sizeof(Long)));
  190.                 printf("%s", buf);
  191.                 break;
  192.             case RATIONAL:
  193.                 readRational(fd, &Rat);
  194.                 printf("%s/", gethex(Rat.numerator, sizeof(Rat.numerator)));
  195.                 sprintf(buf, "0x%lX", Rat.denominator);
  196.                 pad(buf, 2 + (2 * sizeof(Long)));
  197.                 printf("%s", buf);
  198.                 break;
  199.             }
  200.             if ((type != ASCII) && (n % 4 == 3))
  201.                 putchar('\n');
  202.         }
  203.         if (type == ASCII)
  204.             putchar('"');
  205.         if (lseek(fd, oldOffset, 0) < 0) {
  206.             fprintf(stderr, "%s: seek error: %s\n", pgrm, filename);
  207.             exit(1);
  208.         }
  209.     }
  210.     putchar('\n');
  211. }
  212.  
  213. typeSize(type)
  214. Int16    type;
  215. {
  216.     switch (type) {
  217.     case BYTE:
  218.         return(BYTESIZE);
  219.         break;
  220.     case ASCII:
  221.         return(ASCIISIZE);
  222.         break;
  223.     case SHORT:
  224.         return(SHORTSIZE);
  225.         break;
  226.     case LONG:
  227.         return(LONG);
  228.         break;
  229.     case RATIONAL:
  230.         return(RATSIZE);
  231.         break;
  232.     }
  233. }
  234.  
  235. char *tagName(tag)
  236. Int16    tag;
  237. {
  238.     static char buf[80];
  239.     
  240.     switch (tag) {
  241.     case SUBFILE_TYPE_TAG:
  242.         sprintf(buf, "SubfileType");
  243.         break;
  244.     case IMAGE_WIDTH_TAG:
  245.         sprintf(buf, "ImageWidth");
  246.         break;
  247.     case IMAGE_LENGTH_TAG:
  248.         sprintf(buf, "ImageLength");
  249.         break;
  250.     case BITS_PER_SAMPLE_TAG:
  251.         sprintf(buf, "BitsPerSample");
  252.         break;
  253.     case COMPRESSION_TAG:
  254.         sprintf(buf, "Compression");
  255.         break;
  256.     case PHOTOMETRIC_INTERP_TAG:
  257.         sprintf(buf, "PhotometricInterpretation");
  258.         break;
  259.     case THRESHOLDING_TAG:
  260.         sprintf(buf, "Threshholding");
  261.         break;
  262.     case CELL_WIDTH_TAG:
  263.         sprintf(buf, "CellWidth");
  264.         break;
  265.     case CELL_LENGTH_TAG:
  266.         sprintf(buf, "CellLength");
  267.         break;
  268.     case FILL_ORDER_TAG:
  269.         sprintf(buf, "FillOrder");
  270.         break;
  271.     case DOCUMENT_NAME_TAG:
  272.         sprintf(buf, "DocumentName");
  273.         break;
  274.     case IMAGE_DESCRIPTION_TAG:
  275.         sprintf(buf, "ImageDescription");
  276.         break;
  277.     case MAKE_TAG:
  278.         sprintf(buf, "Make");
  279.         break;
  280.     case MODEL_TAG:
  281.         sprintf(buf, "Model");
  282.         break;
  283.     case STRIP_OFFSETS_TAG:
  284.         sprintf(buf, "StripOffsets");
  285.         break;
  286.     case ORIENTATION_TAG:
  287.         sprintf(buf, "Orientation");
  288.         break;
  289.     case SAMPLES_PER_PIXEL_TAG:
  290.         sprintf(buf, "SamplesPerPixel");
  291.         break;
  292.     case ROWS_PER_STRIP_TAG:
  293.         sprintf(buf, "RowsPerStrip");
  294.         break;
  295.     case STRIP_BYTE_COUNTS_TAG:
  296.         sprintf(buf, "StripByteCounts");
  297.         break;
  298.     case MIN_SAMPLE_VALUE_TAG:
  299.         sprintf(buf, "MinSampleValue");
  300.         break;
  301.     case MAX_SAMPLE_VALUE_TAG:
  302.         sprintf(buf, "MaxSampleValue");
  303.         break;
  304.     case X_RESOLUTION_TAG:
  305.         sprintf(buf, "XResolution");
  306.         break;
  307.     case Y_RESOLUTION_TAG:
  308.         sprintf(buf, "YResolution");
  309.         break;
  310.     case PLANAR_CONFIG_TAG:
  311.         sprintf(buf, "PlanarConfiguration");
  312.         break;
  313.     case PAGE_NAME_TAG:
  314.         sprintf(buf, "PageName");
  315.         break;
  316.     case X_POSITION_TAG:
  317.         sprintf(buf, "XPosition");
  318.         break;
  319.     case Y_POSITION_TAG:
  320.         sprintf(buf, "YPosition");
  321.         break;
  322.     case FREE_OFFSETS_TAG:
  323.         sprintf(buf, "FreeOffsets");
  324.         break;
  325.     case FREE_BYTE_COUNTS_TAG:
  326.         sprintf(buf, "FreeByteCounts");
  327.         break;
  328.     case UNITS_GRAY_RESPONSE:
  329.         sprintf(buf, "GrayResponseUnit");
  330.         break;
  331.     case CURVE_GRAY_RESPONSE:
  332.         sprintf(buf, "GrayResponseCurve");
  333.         break;
  334.     case 0x124:    /* Group3Options */
  335.         sprintf(buf, "name");
  336.         break;
  337.     case 0x125:    /* Group4Options */
  338.         sprintf(buf, "name");
  339.         break;
  340.     case 0x128:    /* ResolutionUnit */
  341.         sprintf(buf, "name");
  342.         break;
  343.     case 0x129:    /* PageNumber */
  344.         sprintf(buf, "name");
  345.         break;
  346.     case 0x12C:    /* ColorResponseUnit */
  347.         sprintf(buf, "name");
  348.         break;
  349.     case 0x12D:    /* ColorResponseCurves */
  350.         sprintf(buf, "name");
  351.         break;
  352.     default:
  353.         sprintf(buf, "%03x", tag);
  354.         break;
  355.     }
  356.     pad(buf, strlen("PhotometricInterpretation"));
  357.     return(buf);
  358. }
  359.  
  360. char *typeName(type)
  361. Int16    type;
  362. {
  363.     switch (type) {
  364.     case BYTE:
  365.         return("Byte    ");
  366.         break;
  367.     case ASCII:
  368.         return("Ascii   ");
  369.         break;
  370.     case SHORT:
  371.         return("Short   ");
  372.         break;
  373.     case LONG:
  374.         return("Long    ");
  375.         break;
  376.     case RATIONAL:
  377.         return("Rational");
  378.         break;
  379.     }
  380. }
  381.  
  382. pad(buf, n)
  383. char    *buf;
  384. int        n;
  385. {
  386.     register char    *pStart, *pEnd;
  387.     
  388.     pEnd = buf + n;
  389.     pStart = buf;
  390.     while (*pStart != '\0')
  391.         pStart++;
  392.     while (pStart <= pEnd) {
  393.         *pStart++ = ' ';
  394.     }
  395.     *pStart = '\0';
  396. }
  397.  
  398. unsigned short SwapShortBytes(s)
  399. register unsigned short s;
  400. {
  401.     s = (s >> 8) | (s << 8);
  402.     return(s);
  403. }
  404.  
  405. unsigned long SwapLongBytes(l)
  406. register unsigned long l;
  407. {
  408.     l = ((l >> 24)                )    |
  409.         ((l >>  8) & 0x0000FF00    )    |
  410.         ((l <<  8) & 0x00FF0000    )    |
  411.         ((l << 24)                );
  412.     return(l);
  413. }
  414.  
  415. readByte(fd, byteBuf)
  416. char *byteBuf;
  417. {
  418.     if (read(fd, byteBuf, BYTESIZE) != BYTESIZE) {
  419.         fprintf(stderr, "%s: read error: %s\n", pgrm, filename);
  420.         exit(1);
  421.     }
  422. }
  423.  
  424. readShort(fd, shortBuf)
  425. short *shortBuf;
  426. {
  427.     if (read(fd, shortBuf, SHORTSIZE) != SHORTSIZE) {
  428.         fprintf(stderr, "%s: read error: %s\n", pgrm, filename);
  429.         exit(1);
  430.     }
  431.     if (swapBytes)
  432.         *shortBuf = SwapShortBytes(*shortBuf);
  433. }
  434.  
  435. readLong(fd, longBuf)
  436. long *longBuf;
  437. {
  438.     if (read(fd, longBuf, LONGSIZE) != LONGSIZE) {
  439.         fprintf(stderr, "%s: read error: %s\n", pgrm, filename);
  440.         exit(1);
  441.     }
  442.     if (swapBytes)
  443.         *longBuf = SwapLongBytes(*longBuf);
  444. }
  445.  
  446.  
  447. readRational(fd, ratBuf)
  448. Rational *ratBuf;
  449. {
  450.     if (read(fd, ratBuf, RATSIZE) != RATSIZE) {
  451.         fprintf(stderr, "%s: read error: %s\n", pgrm, filename);
  452.         exit(1);
  453.     }
  454.     if (swapBytes) {
  455.         ratBuf->numerator = SwapLongBytes(ratBuf->numerator);
  456.         ratBuf->denominator = SwapLongBytes(ratBuf->denominator);
  457.     }
  458. }
  459.  
  460. #define LFMTSIZE    2
  461. #define    LMAXDIGITS    8
  462.  
  463. char *gethex(value, size)
  464. int                        size;
  465. register unsigned long    value;
  466. {
  467.     register char            *p;
  468.     register int            i;
  469.     static char                buf[LFMTSIZE + LMAXDIGITS + 1];
  470.     static char                fmt[LFMTSIZE] = "0x";
  471.     
  472.     if ((size * 2) > LMAXDIGITS)
  473.         return("########");
  474.     p = &buf[(size * 2) + LFMTSIZE];
  475.     *p-- = '\0';                            /* null terminate */
  476.     while (value > 0) {                        /* put hex val at end of buffer */
  477.         *p-- = hex(value % 0x10);
  478.         value /= 0x10;
  479.     }
  480.     for (i = (LFMTSIZE - 1); i >= 0 ; i--)    /* prepend format */
  481.         *p-- = fmt[i];
  482.     while (p >= buf)                        /* put in leading blanks */
  483.         *p-- = ' ';
  484.     return(buf);
  485. }
  486.  
  487. char hex(val)
  488. {
  489.     if ((val > 0) && (val < 10))
  490.         return(val + '0');
  491.     else if (val < 0x10)
  492.         return(val - 0xA + 'A');
  493.     else
  494.         return('#');
  495. }